package io.nio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class NioServer2 {
    public static void main(String[] args) throws IOException {
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.bind(new InetSocketAddress(8080));
        System.out.println("服务已启动，监听8080端口");

        Selector selector = Selector.open();

//        SelectionKey serverSelectionKey = serverSocketChannel.register(selector, 0, serverSocketChannel);
//        // 这里为什么要分开指定呢？
//        serverSelectionKey.interestOps(SelectionKey.OP_ACCEPT);

        // 这一句和上面的两句的效果一样？？
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT, serverSocketChannel);

        ByteBuffer buffer = ByteBuffer.allocate(1024);

        while(true) {
            int n = selector.select();
//            if(n == 0)
//                continue;
            Set<SelectionKey> selectionKeys = selector.selectedKeys();
            Iterator<SelectionKey> iterator = selectionKeys.iterator();
            for (;iterator.hasNext();) {
                SelectionKey selectionKey = iterator.next();
                iterator.remove();
                // 准备就绪
                if(selectionKey.isAcceptable()) {
                    System.out.println("有新连接来了");
                    SocketChannel accept;
                    while((accept = serverSocketChannel.accept()) != null) {
                        accept.configureBlocking(false);
                        System.out.println("新建连接：" + accept.getRemoteAddress());
                        accept.register(selector, SelectionKey.OP_READ, accept);
                    }
                } else if(selectionKey.isReadable()) {
                    try {
                        System.out.println("有数据可以读取了");
                        SocketChannel channel = (SocketChannel) selectionKey.attachment();
                        buffer.clear();
                        if (channel.read(buffer) <= 0)
                            continue;
                        buffer.flip();
                        byte[] bytes = new byte[buffer.remaining()];
                        buffer.get(bytes);
                        System.out.println("接收到的数据：" + new String(bytes));
                        System.out.println("数据来自：" + channel.getRemoteAddress());
                        channel.write(ByteBuffer.wrap("HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello World!\r\n".getBytes()));
                        System.out.println("发送响应完毕");
                    } catch (IOException e) {
                        selectionKey.cancel();
                    }
                }
            }
        }
    }
}
